﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using DHQGHN.DAL.Models;

namespace DHQGHN.DAL.DataMapper
{
    public  class BaseMapper : IDataMapper
    {
        private bool _isInitialized = false;
        public Type ModelType{get;set;}

        #region dynamicMapping
        Dictionary<String, String> Map_Dictionary { get; set; }

        public string[] Field_List { get; set; }        

        private List<PropertyInfo> _property_List;
        private List<int> _ordinal_List;
        private List<Type> _type_list;
        #endregion


        /// <summary>
        /// InitializeMapper
        /// </summary>
        /// <param name="reader">dataReader</param>
        


        public void InitializeMapper(IDataReader reader)
        {
            PopulateListOrdinals(reader);
            _isInitialized = true;
        }
        

       
      

        public void PopulateListOrdinals(IDataReader reader)
        {
            _ordinal_List = new List<int>();
            _property_List = new List<PropertyInfo>();
            _type_list = new List<Type>();
            PropertyInfo pro=null;
            foreach (KeyValuePair<String,String> pair in Map_Dictionary)
            {
                pro = ModelType.GetProperty(pair.Key);
                _property_List.Add(pro);
                _ordinal_List.Add(reader.GetOrdinal(pair.Value));
                _type_list.Add(Nullable.GetUnderlyingType(pro.PropertyType) ?? pro.PropertyType);
            }         
         
            _isInitialized = true;
        }
       
       
        public object GetData(System.Data.IDataReader reader)
        {
            if (!_isInitialized)
            {
                InitializeMapper(reader);
            }
            var model = Activator.CreateInstance(ModelType);            
            for (int i = 0; i < _property_List.Count; i++)
            {
                var val = reader.GetValue(_ordinal_List[i]);
                if (val.GetType() != typeof(DBNull))
                {                    
                    _property_List[i].SetValue(model, Convert.ChangeType(val,_type_list[i],null));
                }

            }
            return model;

        }

        /// <summary>
        /// Get Record Count
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        public int GetRecordCount(System.Data.IDataReader reader)
        {
            Object count = reader["RecordCount"];
            return count == null ? 0 : Convert.ToInt32(count);
        }


        public Type[] Field_Type_List
        {
            get
            {
                return Field_Type_List;
            }
            set
            {
                Field_Type_List = value;
            }
        }





        Dictionary<string, string> IDataMapper.Map_Dictionary
        {
            get
            {
                return Map_Dictionary;
            }
            set
            {
                Map_Dictionary = value;
            }
        }
    }
}
